#pragma once
#include "util_public.h"
#include <stdint.h>
#include <memory>
#include <string>

namespace util {
    class UTIL_API CNumber;
    class UTIL_API CReal;
    class UTIL_API CString;

    class UTIL_API COriginType
    {
    public:
        COriginType():m_type(TYPE_UNKNOW){};
        virtual ~COriginType();

        enum TYPE_ENUM
        {
            TYPE_UNKNOW = 0,
            TYPE_NUMBER,
            TYPE_REAL,
            TYPE_STRING
        } m_type;
    };

    class UTIL_API CNumber : public COriginType
    {
    private:
        int64_t m_value;
    public:
        CNumber(){m_type = TYPE_NUMBER;m_value=0;};
        CNumber(const uint8_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const int8_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const uint16_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const int16_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const uint32_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const int32_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const uint64_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const int64_t &b){m_type=TYPE_NUMBER;m_value=b;};
        CNumber(const float &b){m_type=TYPE_NUMBER;m_value=(uint64_t)b;};
        CNumber(const double &b){m_type=TYPE_NUMBER;m_value=(uint64_t)b;};
        ~CNumber();
        int64_t Value() const{return m_value;}

        CNumber& operator=(const CNumber &b){m_value=(const int64_t)b.Value();return *this;};
        CNumber& operator=(const CReal &b);
        CNumber& operator=(const uint8_t &b){m_value=b;return *this;}
        CNumber& operator=(const int8_t &b){m_value=b;return *this;};
        CNumber& operator=(const uint16_t &b){m_value=b;return *this;};
        CNumber& operator=(const int16_t &b){m_value=b;return *this;};
        CNumber& operator=(const uint32_t &b){m_value=b;return *this;};
        CNumber& operator=(const int32_t &b){m_value=b;return *this;};
        CNumber& operator=(const uint64_t &b){m_value=b;return *this;};
        CNumber& operator=(const int64_t &b){m_value=b;return *this;};
        CNumber& operator=(const float &b){m_value=b;return *this;};
        CNumber& operator=(const double &b){m_value=b;return *this;};

        CNumber operator+(const CNumber &b){CNumber _o(m_value+b.Value()); return _o;};
        CNumber operator+(const CReal &b);
        CNumber operator+(const uint8_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const int8_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const uint16_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const int16_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const uint32_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const int32_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const uint64_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const int64_t &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const float &b){CNumber _o(m_value+b); return _o;};
        CNumber operator+(const double &b){CNumber _o(m_value+b); return _o;};

        CNumber operator-(const CNumber &b){CNumber _o(m_value-b.Value()); return _o;};
        CNumber operator-(const CReal &b);
        CNumber operator-(const uint8_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const int8_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const uint16_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const int16_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const uint32_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const int32_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const uint64_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const int64_t &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const float &b){CNumber _o(m_value-b); return _o;};
        CNumber operator-(const double &b){CNumber _o(m_value-b); return _o;};

        CNumber operator*(const CNumber &b){CNumber _o(m_value*b.Value()); return _o;};
        CNumber operator*(const CReal &b);
        CNumber operator*(const uint8_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const int8_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const uint16_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const int16_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const uint32_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const int32_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const uint64_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const int64_t &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const float &b){CNumber _o(m_value*b); return _o;};
        CNumber operator*(const double &b){CNumber _o(m_value*b); return _o;};

        CNumber operator/(const CNumber &b){CNumber _o(m_value/b.Value()); return _o;};
        CNumber operator/(const CReal &b);
        CNumber operator/(const uint8_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const int8_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const uint16_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const int16_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const uint32_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const int32_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const uint64_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const int64_t &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const float &b){CNumber _o(m_value/b); return _o;};
        CNumber operator/(const double &b){CNumber _o(m_value/b); return _o;};

        CNumber operator%(const CNumber &b){CNumber _o(m_value%b.Value()); return _o;};
        CNumber operator%(const uint8_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const int8_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const uint16_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const int16_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const uint32_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const int32_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const uint64_t &b){CNumber _o(m_value%b); return _o;};
        CNumber operator%(const int64_t &b){CNumber _o(m_value%b); return _o;};

        CNumber operator++(){++m_value; return *this;};
        CNumber operator++(int){m_value++; return *this;};
        CNumber operator--(){--m_value; return *this;};
        CNumber operator--(int){m_value--; return *this;};

    };

    class UTIL_API CReal : public COriginType
    {
    private:
        double   m_value;
    public:
        CReal(){m_type = TYPE_REAL;m_value=0.0;};
        CReal(const uint8_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const int8_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const uint16_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const int16_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const uint32_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const int32_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const uint64_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const int64_t &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const float &b){m_type=TYPE_REAL;m_value=b;};
        CReal(const double &b){m_type=TYPE_REAL;m_value=b;};
        ~CReal();
        double Value()const{return m_value;};

        CReal& operator=(const CNumber &b){this->m_value=b.Value();return *this;};
        CReal& operator=(const CReal &b){m_value=b.Value();return *this;};
        CReal& operator=(const uint8_t &b){m_value=b;return *this;};
        CReal& operator=(const int8_t &b){m_value=b;return *this;};
        CReal& operator=(const uint16_t &b){m_value=b;return *this;};
        CReal& operator=(const int16_t &b){m_value=b;return *this;};
        CReal& operator=(const uint32_t &b){m_value=b;return *this;};
        CReal& operator=(const int32_t &b){m_value=b;return *this;};
        CReal& operator=(const uint64_t &b){m_value=b;return *this;};
        CReal& operator=(const int64_t &b){m_value=b;return *this;};
        CReal& operator=(const float &b){m_value=b;return *this;};
        CReal& operator=(const double &b){m_value=b;return *this;};

        CReal operator+(const CNumber &b){CReal _o(m_value+b.Value()); return _o;};
        CReal operator+(const CReal &b){CReal _o(m_value+b.Value()); return _o;};
        CReal operator+(const uint8_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const int8_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const uint16_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const int16_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const uint32_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const int32_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const uint64_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const int64_t &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const float &b){CReal _o(m_value+b); return _o;};
        CReal operator+(const double &b){CReal _o(m_value+b); return _o;};

        CReal operator-(const CNumber &b){CReal _o(m_value-b.Value()); return _o;};
        CReal operator-(const CReal &b){CReal _o(m_value-b.Value()); return _o;};
        CReal operator-(const uint8_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const int8_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const uint16_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const int16_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const uint32_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const int32_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const uint64_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const int64_t &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const float &b){CReal _o(m_value-b); return _o;};
        CReal operator-(const double &b){CReal _o(m_value-b); return _o;};

        CReal operator*(const CNumber &b){CReal _o(m_value*b.Value()); return _o;};
        CReal operator*(const CReal &b){CReal _o(m_value*b.Value()); return _o;};
        CReal operator*(const uint8_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const int8_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const uint16_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const int16_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const uint32_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const int32_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const uint64_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const int64_t &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const float &b){CReal _o(m_value*b); return _o;};
        CReal operator*(const double &b){CReal _o(m_value*b); return _o;};

        CReal operator/(const CNumber &b){CReal _o(m_value/b.Value()); return _o;};
        CReal operator/(const CReal &b){CReal _o(m_value/b.Value()); return _o;};
        CReal operator/(const uint8_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const int8_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const uint16_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const int16_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const uint32_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const int32_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const uint64_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const int64_t &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const float &b){CReal _o(m_value/b); return _o;};
        CReal operator/(const double &b){CReal _o(m_value/b); return _o;};
    };

    class UTIL_API CString : public COriginType
    {
    private:
        std::string m_value;
    public:
        CString(){m_type=TYPE_STRING;};
        CString(const uint8_t &b) {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const int8_t &b)  {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const uint16_t &b){m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const int16_t &b) {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const uint32_t &b){m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const int32_t &b) {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const uint64_t &b){m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const int64_t &b) {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const float &b)   {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const double &b)  {m_type=TYPE_STRING;m_value= std::to_string(b);};
        CString(const char *b)    {m_type=TYPE_STRING;m_value=b?b:"";};
        CString(const std::string &b)  {m_type=TYPE_STRING;m_value=b;};
        ~CString();
        std::string& Value(){return m_value;};

        CString operator+(const CNumber &b) {CString _o(m_value+ std::to_string(b.Value())); return _o;};
        CString operator+(const CReal &b)   {CString _o(m_value+ std::to_string(b.Value())); return _o;};
        CString operator+(const CString &b) {CString _o(m_value+b.m_value);    return _o;};
        CString operator+(const uint8_t &b) {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const int8_t &b)  {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const uint16_t &b){CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const int16_t &b) {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const uint32_t &b){CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const int32_t &b) {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const uint64_t &b){CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const int64_t &b) {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const float &b)   {CString _o(m_value+ std::to_string(b)); return _o;};
        CString operator+(const double &b)  {CString _o(m_value+ std::to_string(b)); return _o;};
    };

    class UTIL_API CVariable : public COriginType {
    private:
        int64_t m_number;
        double  m_real;
        std::string  m_string;

    public:
        CVariable(){m_type = TYPE_UNKNOW;m_number=0; m_real=0.0;};
        CVariable(const uint8_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const int8_t &b)  {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const uint16_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const int16_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const uint32_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const int32_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const uint64_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const int64_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;};
        CVariable(const float &b)   {m_type=TYPE_REAL;  m_number=0;m_real=b;};
        CVariable(const double &b)  {m_type=TYPE_REAL;  m_number=0;m_real=b;};
        CVariable(const char* b)    {m_type=TYPE_STRING;m_number=0;m_real=0.0;m_string=b?b:"";};
        CVariable(const std::string b)   {m_type=TYPE_STRING;m_number=0;m_real=0.0;m_string=b;};
        CVariable(const CVariable &b){m_type=b.m_type; m_number=b.m_number;m_real=b.m_real;m_string=b.m_string;};
        ~CVariable();
        int64_t ToNumber() const{
            if(m_type==TYPE_NUMBER)
                return m_number;
            if(m_type==TYPE_REAL)
                return m_real;
            if(m_type==TYPE_STRING)
                return stoll(m_string);
            return 0;
        }
        double ToReal() const {
            if(m_type==TYPE_NUMBER)
                return m_number;
            if(m_type==TYPE_REAL)
                return m_real;
            if(m_type==TYPE_STRING)
                return stod(m_string);
            return 0.0;
        }
        std::string ToString() const {
            if(m_type==TYPE_NUMBER)
                return std::to_string(m_number);
            if(m_type==TYPE_REAL)
                return std::to_string(m_real);
            if(m_type==TYPE_STRING)
                return m_string;
            return "";
        }
        TYPE_ENUM Type() const {return m_type;};

        CVariable& operator=(const CVariable &b){m_type=b.m_type; m_number=b.m_number;m_real=b.m_real;m_string=b.m_string; return *this;};
        CVariable& operator=(const uint8_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const int8_t &b)  {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const uint16_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const int16_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const uint32_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const int32_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const uint64_t &b){m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const int64_t &b) {m_type=TYPE_NUMBER;m_number=b;m_real=0.0;m_string=""; return *this;};
        CVariable& operator=(const float &b)   {m_type=TYPE_REAL;  m_number=0;m_real=b;  m_string=""; return *this;};
        CVariable& operator=(const double &b)  {m_type=TYPE_REAL;  m_number=0;m_real=b;  m_string=""; return *this;};
        CVariable& operator=(const char* b)    {m_type=TYPE_STRING;m_number=0;m_real=0.0;m_string=b?b:""; return *this;};
        CVariable& operator=(const std::string b)   {m_type=TYPE_STRING;m_number=0;m_real=0.0;m_string=b; return *this;};

        CVariable operator+(const CVariable &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b.ToNumber()); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b.ToReal()); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+b.ToString()); 
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const uint8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const int8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const uint16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const int16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const uint32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const int32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const uint64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const int64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const float &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };
        CVariable operator+(const double &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number+b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real+b); 
                return _o;
            }
            if(m_type==TYPE_STRING) {
                CVariable _o(m_string+ std::to_string(b));
                return _o;
            }
            CVariable _o(b);
            return _o;
        };

        CVariable operator-(const CVariable &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b.ToNumber()); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b.ToReal()); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const uint8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const int8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const uint16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const int16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const uint32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const int32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const uint64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const int64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const float &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator-(const double &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number-b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real-b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };

        CVariable operator*(const CVariable &b){
            if(m_type==TYPE_REAL || b.m_type == TYPE_REAL) {
                CVariable _o(ToReal()*b.ToReal()); 
                return _o;
            }
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b.ToNumber()); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const uint8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const int8_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const uint16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const int16_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const uint32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const int32_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const uint64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const int64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number*b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real*b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator*(const float &b){
            CVariable _o(ToReal()*b); 
            return _o;
        };
        CVariable operator*(const double &b){
            CVariable _o(ToReal()*b); 
            return _o;
        };

        CVariable operator/(const CVariable &b){
            if(m_type==TYPE_REAL || b.m_type==TYPE_REAL) {
                CVariable _o(ToReal()/b.ToReal()); 
                return _o;
            }
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number/b.ToNumber()); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator/(const int64_t &b){
            if(m_type==TYPE_NUMBER){
                CVariable _o(m_number/b); 
                return _o;
            }
            if(m_type==TYPE_REAL) {
                CVariable _o(m_real/b); 
                return _o;
            }
            CVariable _o(*this);
            return _o;
        };
        CVariable operator/(const uint64_t &b){return (*this)/(const int64_t)b;};
        CVariable operator/(const uint8_t &b) {return (*this)/(const int64_t)b;};
        CVariable operator/(const int8_t &b)  {return (*this)/(const int64_t)b;};
        CVariable operator/(const uint16_t &b){return (*this)/(const int64_t)b;};
        CVariable operator/(const int16_t &b) {return (*this)/(const int64_t)b;};
        CVariable operator/(const uint32_t &b){return (*this)/(const int64_t)b;};
        CVariable operator/(const int32_t &b) {return (*this)/(const int64_t)b;};
        CVariable operator/(const float &b)   {CVariable _o(ToReal()*b); return _o;};
        CVariable operator/(const double &b)  {CVariable _o(ToReal()*b); return _o;};

        CVariable operator%(const CVariable &b){CVariable _o(ToNumber()%b.ToNumber()); return _o;};
        CVariable operator%(const int64_t &b)  {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const uint8_t &b)  {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const int8_t &b)   {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const uint16_t &b) {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const int16_t &b)  {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const uint32_t &b) {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const int32_t &b)  {CVariable _o(ToNumber()%b); return _o;};
        CVariable operator%(const uint64_t &b) {CVariable _o(ToNumber()%b); return _o;};

        CVariable operator++()   {if(m_type==TYPE_NUMBER)++m_number; return *this;};
        CVariable operator++(int){if(m_type==TYPE_NUMBER)m_number++; return *this;};
        CVariable operator--()   {if(m_type==TYPE_NUMBER)--m_number; return *this;};
        CVariable operator--(int){if(m_type==TYPE_NUMBER)--m_number; return *this;};
    };
}